package com.yyw.gulimall.member.service.impl;

import cn.gjing.http.HttpClient;
import cn.gjing.http.HttpMethod;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yyw.common.constant.common.UrlConstant;
import com.yyw.common.enums.common.OAuth2SourceEnum;
import com.yyw.common.exception.OAuth2FeignException;
import com.yyw.gulimall.member.abstracts.RootOAuth2Service;
import com.yyw.gulimall.member.entity.MemberEntity;
import com.yyw.gulimall.member.entity.MemberLevelEntity;
import com.yyw.gulimall.member.entity.MemberOauth2Entity;
import com.yyw.gulimall.member.service.MemberLevelService;
import com.yyw.gulimall.member.service.MemberOauth2Service;
import com.yyw.gulimall.member.vo.weibo.AccessTokenResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Classname WeiboOAuth2ServiceImpl
 * @Description 微博认证服务
 * @Date 2020/12/16 11:06
 * @Created yyw
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class WeiboOAuth2ServiceImpl extends RootOAuth2Service {
    private final MemberLevelService memberLevelService;
    private final MemberOauth2Service memberOauth2Service;
    private final ThreadPoolExecutor threadPoolExecutor;

    /**
     * 根据传入的AccessToken 封装成 第三方登录数据表， 统一数据传输
     *
     * @param tokenResult
     * @return
     */
    @Override
    public MemberOauth2Entity packageData(AccessTokenResult tokenResult) {
        MemberOauth2Entity oauth2Entity = MemberOauth2Entity.builder().accessToken(tokenResult.getAccess_token())
                .expiresIn(tokenResult.getExpires_in())
                .source(OAuth2SourceEnum.OAUTH2_WEIBO.getCode())
                .uid(tokenResult.getUid())
                .build();
        return oauth2Entity;
    }


    /**
     * 封装Member 会员数据
     * 用于保存会员信息
     *
     * @param tokenResult
     * @return
     */
    @Override
    public MemberEntity packageDataByMember(AccessTokenResult tokenResult) {
        // 封装会员信息
        MemberEntity entity = MemberEntity.builder()
                .createTime(new Date())
                .sourceType(OAuth2SourceEnum.OAUTH2_WEIBO.getCode())
                .status(1).build();

        // 3. 查询默认等级
        CompletableFuture<Void> runAsync = CompletableFuture.runAsync(() -> {
            MemberLevelEntity levelEntity = memberLevelService.getOne(new QueryWrapper<MemberLevelEntity>()
                    .lambda().eq(MemberLevelEntity::getDefaultStatus, 1));
            entity.setLevelId(Objects.equals(null, levelEntity) ? -1 : levelEntity.getId());
        }, threadPoolExecutor);
        try {
            // 向微博发送请求，获取用户数据
            CompletableFuture<Void> runAsync1 = CompletableFuture.runAsync(() -> {
                Map<String, String> map = new HashMap<>();
                map.put("access_token", tokenResult.getAccess_token());
                map.put("uid", tokenResult.getUid());
                String result = HttpClient.builder(UrlConstant.AUTH_WEIBO_USER_INFO_URL, HttpMethod.GET, String.class)
                        .param(map)
                        .fallback(e -> {
                            log.error("获取新浪微博用户信息失败，{}", e);
                            throw new OAuth2FeignException("获取新浪微博用户信息失败，" + e);
                        })
                        .execute().get();
                JSONObject jsonObject = JSON.parseObject(result);
                String screen_name = jsonObject.get("screen_name").toString();  // 获取用户昵称
                String gender = jsonObject.get("gender").toString();  // 获取用户性别
                String avatarHd = jsonObject.get("avatar_hd").toString();  // 获取用户头像地址
                String location = jsonObject.get("location").toString();  // 获取用户所在地
                entity.setNickname(screen_name);
                entity.setGender("m".equalsIgnoreCase(gender) ? 1 : 0);
                entity.setHeader(avatarHd);
                entity.setCity(location);
            }, threadPoolExecutor);

            // 等待完成
            CompletableFuture.allOf(runAsync, runAsync1).get();

        } catch (Exception e) {
            // 发送了异常，就不操作了，直接保存默认值
            log.error("发送了错误: {}", e);
        }

        return entity;
    }

    /**
     * 根据来源 获取第三方登录数据 判断是否第一次登录
     *
     * @param memberOauth2Entity
     * @return
     */
    @Override
    public MemberOauth2Entity getInfoBySource(MemberOauth2Entity memberOauth2Entity) {
        QueryWrapper<MemberOauth2Entity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MemberOauth2Entity::getUid, memberOauth2Entity.getUid())
                .eq(MemberOauth2Entity::getSource, memberOauth2Entity.getSource());
        return memberOauth2Service.getOne(queryWrapper);
    }
}
